package com.swu.pad.reflection.service.impl;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.swu.pad.assignment.dao.AssignmentDao;
import com.swu.pad.assignment.dao.AssignmentPadDao;
import com.swu.pad.assignment.entity.Assignment;
import com.swu.pad.course.dao.CourseGroupUserDao;
import com.swu.pad.reflection.dao.ModifiedSentenceDao;
import com.swu.pad.reflection.dao.ReflectionFbItemDao;
import com.swu.pad.reflection.dao.ReflectionScoreDao;
import com.swu.pad.reflection.dao.RftDimTipTemplateDao;
import com.swu.pad.reflection.dao.RftDimTipsDao;
import com.swu.pad.reflection.dao.RftFbItemScoreDao;
import com.swu.pad.reflection.dao.RftFeedbackTemplateDao;
import com.swu.pad.reflection.dao.SentenceClassDao;
import com.swu.pad.reflection.entity.ModifiedSentence;
import com.swu.pad.reflection.entity.ReflectionScore;
import com.swu.pad.reflection.entity.RftDimTipTemplate;
import com.swu.pad.reflection.entity.RftDimTips;
import com.swu.pad.reflection.entity.RftFbItemScore;
import com.swu.pad.reflection.entity.RftFeedbackItem;
import com.swu.pad.reflection.entity.RftFeedbackTemplate;
import com.swu.pad.reflection.entity.RftFeedbackTemplate;
import com.swu.pad.reflection.entity.SentenceClass;
import com.swu.pad.reflection.service.ReflectionService;
import com.swu.pad.system.entity.User;
import com.swu.pad.util.DocToSentencesClassUtil;
import com.swu.pad.util.TimeUtil;
import com.swu.pad.util.EPLiteClient.EPLiteClient;

import java_cup.internal_error;

@Service
@Transactional
public class ReflectionServiceImpl implements ReflectionService {

	@Autowired
	private RftDimTipsDao rftDimTipsDao;
	@Autowired
	private AssignmentPadDao aspDao;
	@Autowired
	private CourseGroupUserDao cguDao;
	@Autowired
	private ReflectionScoreDao rftSDao;
	@Autowired
	private SentenceClassDao stcDao;
	@Autowired
	private EPLiteClient epliteClient;
	@Autowired
	private RftFeedbackTemplateDao rftFbTptDao;
	@Autowired
	private ReflectionFbItemDao rftFbItemDao;
	@Autowired
	private AssignmentDao asmDao;
	@Autowired
	private RftDimTipTemplateDao rftDTTDao;
	@Autowired
	private RftFbItemScoreDao rftFbItemScoreDao;
	@Autowired
	private ModifiedSentenceDao mdfStcDao;


	// 保存学生在某次 反思作业下 某个反思维度下的得分
	@Override
	public void saveReflectionScore(ReflectionScore reflectionScore) {
		reflectionScore.setTimeStamp(TimeUtil.getStringDate());
		rftSDao.saveAndFlush(reflectionScore);
	}

	// 获得某位同学某次作业反思得分
	@Override
	public Map<String, Object> getStuRftScore(String studentId, String assignmentId) {
		Map<String, Object> res = new HashMap<String, Object>();
        Assignment assignment=asmDao.findOne(assignmentId);
        //获取作业 提示与打分模板id    修改为根据模板id 获取得分
		List<ReflectionScore> rftScores = rftSDao.findByTemplateIdAndStuId(assignment.getRftDimTipTptId(),studentId);
		List<ReflectionScore> rftNewScores = new ArrayList<ReflectionScore>();

		for (int i = 0; i < rftScores.size(); i++) {
			if (rftNewScores.size() == 0) {// 可以直接add
				rftNewScores.add(rftScores.get(i));
			} else {
				boolean hasOne = false;
				for (int j = 0; j < rftNewScores.size(); j++) {
					if (rftNewScores.get(j).getRftDimId().equals(rftScores.get(i).getRftDimId())) {// 说明出现过
						hasOne = true;
					}
				}
				if (hasOne == false) {
					rftNewScores.add(rftScores.get(i));// 添加
				}
			}
		} // 构建互斥队列完成，新队列只含有一次 该维度打分

		for (int i = 0; i < rftNewScores.size(); i++) {
			ReflectionScore temp = new ReflectionScore();
			boolean change = false;
			for (int j = 0; j < rftScores.size(); j++) {
				if (rftNewScores.get(i).getRftDimId().equals(rftScores.get(j).getRftDimId())) {
					if (rftNewScores.get(i).getTimeStamp().compareTo(rftScores.get(j).getTimeStamp()) < 0) {
						temp = rftScores.get(j);
						change = true;
					}
				}
			}
			if (change) {// 变了
				rftNewScores.set(i, temp);// 替换
			}

		}
		res.put("score", rftNewScores);
		List<RftDimTips> temps = new ArrayList<RftDimTips>();
		for (ReflectionScore rftScore : rftNewScores) {
			RftDimTips rft = rftDimTipsDao.findOne(rftScore.getRftDimId());
			temps.add(rft);
		}
		res.put("rftDims", temps);
		return res;
	}

	// 获取 反思文本 句子自动 分类结果 信息
	@Override
	public Map<String, Object> getTextSentenceClass(String padId, String activityId, User user) throws Exception {
		Map<String, Object> resMap = new HashMap<String, Object>();
		List<SentenceClass> resSentences = new ArrayList<SentenceClass>();// 存储返回的句子信息
		List<List<String>> classIndexAndValues = DocToSentencesClassUtil.getClassInfos();// 存 句子 类别 下标 和 名称 等具体信息
		// 1 判断作者是不是第一次 使用文本分析功能
		List<SentenceClass> sentences = stcDao.findByPadIdAndActivityId(padId, activityId);
		if (sentences.size() == 0) {
			// 2 如果 是 先把句子保存一遍
			// 2.1获取 作者 文章
			Map<String, Object> pdTmap = new HashMap<String, Object>();
			pdTmap = epliteClient.getText(padId);// getText默认返回最新版本的 text
			String docText = (String) pdTmap.get("text");
			List<Map<String, Object>> versions = epliteClient.getAllRevisions(padId);
			// 2.2 保存最后一个版本号
			String padLastVersion = Integer.toString((Integer) versions.get(versions.size() - 1).get("revs"));
			// classInfo [[0, self_critique, 自我批判, 反思自己的不足], sentenceInfo 所有句子信息
			Map<String, Object> sentenceClassInfo = DocToSentencesClassUtil.docSentenceClass(docText);
			// 所有句子信息 {sentence：句子内容，class= 中文 标签}
			List<Map<String, Object>> sentencesInfo = (List<Map<String, Object>>) sentenceClassInfo.get("sentenceInfo");
			// 保存每条句子信息
			for (int i = 0; i < sentencesInfo.size(); i++) {
				SentenceClass sentence = new SentenceClass();// id自动生成 uuid 不创建
				sentence.setContent(sentencesInfo.get(i).get("sentence").toString());
				sentence.setSentenceClass(sentencesInfo.get(i).get("class").toString());
				sentence.setVersionNum(padLastVersion);
				sentence.setMarker("cpu");
				sentence.setPadId(padId);
				sentence.setStuId(user.getId());
				sentence.setActivityId(activityId);
				stcDao.save(sentence);// 调用dao保存句子实体
				resSentences.add(sentence);
			}
			resMap.put("versionNum",padLastVersion);
			resMap.put("sentenceInfo", resSentences);
			resMap.put("classInfo", classIndexAndValues);
		} else {// 3如果不是 看最后的版本号有没有变
				// 判断版本号
				// 3.1获取 作者 文章
			int flag = 1;
			Map<String, Object> pdTmap = new HashMap<String, Object>();
			pdTmap = epliteClient.getText(padId);// getText默认返回最新版本的 text
			String docText = (String) pdTmap.get("text");
			List<Map<String, Object>> versions = epliteClient.getAllRevisions(padId);
			// 3.2 保存最后一个版本号
			String padLastVersion = Integer.toString((Integer) versions.get(versions.size() - 1).get("revs"));
			for (int i = 0; i < sentences.size(); i++) {
				if (sentences.get(i).getVersionNum().equals(padLastVersion)) {// 说明没变
					flag = 0;
					break;
				}
			}
			if (flag == 0) {// 版本没变
				for (int i = 0; i < sentences.size(); i++) {
					if (sentences.get(i).getVersionNum().equals(padLastVersion)) {
						resSentences.add(sentences.get(i));
					}
				}
				resMap.put("versionNum",padLastVersion);
				resMap.put("sentenceInfo", resSentences);
				resMap.put("classInfo", classIndexAndValues);
			} else {// 变了就再保存一遍 新的 句子列表
				Map<String, Object> sentenceClassInfo = DocToSentencesClassUtil.docSentenceClass(docText);
				// 所有句子信息 {sentence：句子内容，class= 中文 标签}
				List<Map<String, Object>> sentencesInfo = (List<Map<String, Object>>) sentenceClassInfo.get("sentenceInfo");
				// 保存每条句子信息
				for (int i = 0; i < sentencesInfo.size(); i++) {
					SentenceClass sentence = new SentenceClass();// id自动生成 uuid 不创建
					sentence.setContent(sentencesInfo.get(i).get("sentence").toString());
					sentence.setSentenceClass(sentencesInfo.get(i).get("class").toString());
					sentence.setVersionNum(padLastVersion);
					sentence.setMarker("cpu");
					sentence.setPadId(padId);
					sentence.setStuId(user.getId());
					sentence.setActivityId(activityId);
					stcDao.save(sentence);// 调用dao保存句子实体
					resSentences.add(sentence);
				}
				resMap.put("versionNum",padLastVersion);
				resMap.put("sentenceInfo", resSentences);
				resMap.put("classInfo", classIndexAndValues);
			}
		}
        
		//计算每个class的比例  构建一个比例 map
		Map<String,String> classProportion=new HashMap<String, String>();
		List<List<String>> cIAValues=(List<List<String>>)resMap.get("classInfo");
		List<SentenceClass>  senceInfos=(List<SentenceClass>) resMap.get("sentenceInfo");
		for (int i = 0; i < cIAValues.size();i++) {
			classProportion.put(cIAValues.get(i).get(2),"0");//初始 比例为0
		}
		int sentenceCount=senceInfos.size();//句子总数
		for (int i = 0; i < senceInfos.size(); i++) {
			classProportion.put(senceInfos.get(i).getSentenceClass(),Integer.toString(Integer.parseInt(classProportion.get(senceInfos.get(i).getSentenceClass()))+1));
		}
		//遍历 map 设置比值
		// 创建一个数值格式化对象   
		NumberFormat numberFormat = NumberFormat.getInstance();   
		// 设置精确到小数点后2位   
		numberFormat.setMaximumFractionDigits(2);   
		for (String key : classProportion.keySet()) {
			int classNum=Integer.parseInt(classProportion.get(key));//该类别句子数量
			String result = numberFormat.format((float)classNum/(float)sentenceCount*100);
			classProportion.put(key,result);
	    }
		resMap.put("classProportion", classProportion);
		return resMap;
	}

	/*
	 * 修改句子类别 (non-Javadoc)
	 * 
	 * @see
	 * com.swu.pad.reflection.service.ReflectionService#modifySentenceClass(java.
	 * lang.String, java.lang.String)
	 */
	@Override
	public void modifySentenceClass(String sentenceId,String sentenceClass) {
		SentenceClass sentence = stcDao.findOne(sentenceId);
		String beforeSentenceClass=sentence.getSentenceClass();
		sentence.setMarker("stu");
		sentence.setSentenceClass(sentenceClass);
		stcDao.saveAndFlush(sentence);
		//插入新 的修改后的句子到数据库的新修改后的句子表
		ModifiedSentence mSentence=new ModifiedSentence();
		mSentence.setActivityId(sentence.getActivityId());
		mSentence.setInitialSentenceId(sentence.getId());
		mSentence.setModifyTime(TimeUtil.getStringDate());
		mSentence.setSentenceClassBefore(beforeSentenceClass);
		mSentence.setSentenceClassAfter(sentenceClass);
		mSentence.setUserId(sentence.getStuId());
		mSentence.setVersionNum(sentence.getVersionNum());
		mdfStcDao.saveAndFlush(mSentence);
		
		
	}

	/*
	 * 查看所有句子类别 ， 学生 点击了 查看按钮 并不需要 查看最新的 (non-Javadoc)
	 * 
	 * @see
	 * com.swu.pad.reflection.service.ReflectionService#querySentences(java.lang.
	 * String, java.lang.String, com.swu.pad.system.entity.User)
	 */
	@Override
	public Map<String, Object> querySentences(String padId, String activityId, User user) throws Exception {
		Map<String, Object> resMap = new HashMap<String, Object>();
		List<SentenceClass> resSentences = new ArrayList<SentenceClass>();// 存储返回的句子信息
		List<List<String>> classIndexAndValues = DocToSentencesClassUtil.getClassInfos();// 存 句子 类别 下标 和 名称 等具体信息
		// 1 判断作者是不是第一次 使用文本分析功能
		List<SentenceClass> sentences = stcDao.findByPadIdAndActivityId(padId, activityId);
		if (sentences.size() == 0) {
			// 2 如果 是 先把句子保存一遍
			// 2.1获取 作者 文章
			Map<String, Object> pdTmap = new HashMap<String, Object>();
			pdTmap = epliteClient.getText(padId);// getText默认返回最新版本的 text
			String docText = (String) pdTmap.get("text");
			List<Map<String, Object>> versions = epliteClient.getAllRevisions(padId);
			// 2.2 保存最后一个版本号
			String padLastVersion = Integer.toString((Integer) versions.get(versions.size() - 1).get("revs"));
			//System.out.println(padLastVersion);
			// classInfo [[0, self_critique, 自我批判, 反思自己的不足], sentenceInfo 所有句子信息
			Map<String, Object> sentenceClassInfo = DocToSentencesClassUtil.docSentenceClass(docText);
			// 所有句子信息 {sentence：句子内容，class= 中文 标签}
			List<Map<String, Object>> sentencesInfo = (List<Map<String, Object>>) sentenceClassInfo.get("sentenceInfo");
			// 保存每条句子信息
			for (int i = 0; i < sentencesInfo.size(); i++) {
				SentenceClass sentence = new SentenceClass();// id自动生成 uuid 不创建
				sentence.setContent(sentencesInfo.get(i).get("sentence").toString());
				sentence.setSentenceClass(sentencesInfo.get(i).get("class").toString());
				sentence.setVersionNum(padLastVersion);
				sentence.setMarker("cpu");
				sentence.setPadId(padId);
				sentence.setStuId(user.getId());
				sentence.setActivityId(activityId);
				stcDao.save(sentence);// 调用dao保存句子实体
				resSentences.add(sentence);
			}
			resMap.put("versionNum",padLastVersion);
			resMap.put("sentenceInfo", resSentences);
			resMap.put("classInfo", classIndexAndValues);
		} else {// 3 如果不是 ，说明不是，说明数据库至少有一个版本，查询出最后一个版本 返回
				// 找到数据库最大的版本号
			String lastVersion = sentences.get(0).getVersionNum();
			for (int i = 0; i < sentences.size(); i++) {
				if (Integer.parseInt(sentences.get(i).getVersionNum()) > Integer.parseInt(lastVersion)) {
					lastVersion = sentences.get(i).getVersionNum();
				}
			}

			for (int i = 0; i < sentences.size(); i++) {
				if (sentences.get(i).getVersionNum().equals(lastVersion)) {
					resSentences.add(sentences.get(i));
				}
			}
			resMap.put("versionNum",lastVersion);
			resMap.put("sentenceInfo", resSentences);
			resMap.put("classInfo", classIndexAndValues);
		}
		
		//计算每个class的比例  构建一个比例 map
				Map<String,String> classProportion=new HashMap<String, String>();
				Map<String,String> classCountNum=new HashMap<String, String>();//存储每个类别出现的数量
				List<List<String>> cIAValues=(List<List<String>>)resMap.get("classInfo");
				List<SentenceClass>  senceInfos=(List<SentenceClass>) resMap.get("sentenceInfo");
				for (int i = 0; i < cIAValues.size();i++) {
					classProportion.put(cIAValues.get(i).get(2),"0");//初始 比例为0
					classCountNum.put(cIAValues.get(i).get(2),"0");//初始化为0
				}
				int sentenceCount=senceInfos.size();//句子总数
				for (int i = 0; i < senceInfos.size(); i++) {
					classProportion.put(senceInfos.get(i).getSentenceClass(),Integer.toString(Integer.parseInt(classProportion.get(senceInfos.get(i).getSentenceClass()))+1));
					classCountNum.put(senceInfos.get(i).getSentenceClass(),Integer.toString(Integer.parseInt(classCountNum.get(senceInfos.get(i).getSentenceClass()))+1));
				}
				//遍历 map 设置比值
				// 创建一个数值格式化对象   
				NumberFormat numberFormat = NumberFormat.getInstance();   
				// 设置精确到小数点后2位   
				numberFormat.setMaximumFractionDigits(2);   
				for (String key : classProportion.keySet()) {
					int classNum=Integer.parseInt(classProportion.get(key));//该类别句子数量
					String result = numberFormat.format((float)classNum/(float)sentenceCount*100);
					classProportion.put(key,result);
			    }
				resMap.put("classCountNum",classCountNum);
				resMap.put("classProportion", classProportion);
		
		
		return resMap;
	}

	/*
	 * 创建反思写作反馈模板 (non-Javadoc)
	 * 
	 * @see
	 * com.swu.pad.reflection.service.ReflectionService#saveOrUpdaterftFbTemplate(
	 * com.swu.pad.reflection.entity.RtfFeedbackTemplate)
	 */
	@Override
	public RftFeedbackTemplate saveOrUpdaterftFbTemplate(RftFeedbackTemplate rtfFeedbackTemplate) {
		return rftFbTptDao.saveAndFlush(rtfFeedbackTemplate);
	}

	/*
	 * 获取所有反思写作反馈模板列表 (non-Javadoc)
	 * 
	 * @see com.swu.pad.reflection.service.ReflectionService#getRftFbTemplates()
	 */
	@Override
	public List<RftFeedbackTemplate> getRftFbTemplates() {
		return rftFbTptDao.findAll();
	}
    
	/*
	 * 根据模板id删除反思写作反馈模板
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#deleteRftFbTemplate(java.lang.String)
	 */
	@Override
	public void deleteRftFbTemplate(String templateId) {
		 rftFbTptDao.delete(templateId); 
		 List<RftFeedbackItem> rftFbItems=rftFbItemDao.findByTemplateId(templateId);
		 for (int i = 0; i < rftFbItems.size(); i++) {
			 rftFbItemDao.delete(rftFbItems.get(i));//删除模板关联  条目
		}
	}
    
	/*保存 或者 修改 反馈模板 条目
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#saveOrUpdateRftFbItem(com.swu.pad.reflection.entity.RftFeedbackItem)
	 */
	@Override
	public RftFeedbackItem saveOrUpdateRftFbItem(RftFeedbackItem rftFeedbackItem) {
		return rftFbItemDao.saveAndFlush(rftFeedbackItem);
	}
   
	/*获取 一个模板 所有条目
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#getRftFbItems(java.lang.String)
	 */
	@Override
	public List<RftFeedbackItem> getRftFbItems(String templateId) {
		return rftFbItemDao.findByTemplateId(templateId);
	}
    //删除一个 反馈 模板  的一个条目
	@Override
	public void deleteRftFbItem(String itemId) {
		rftFbItemDao.delete(itemId);
	}
    
	//获取 一个作业下 一个反馈模板 和  所有条目
	@Override
	public Map<String, Object> getRftFbTptItems(String assignmentId) {
		Map<String, Object> resultMap=new HashMap<String, Object>();
		Assignment assignment=asmDao.findOne(assignmentId);
		RftFeedbackTemplate rftFbTpt=rftFbTptDao.findOne(assignment.getRftFbTptId());
		List<RftFeedbackItem> rftFbItems=rftFbItemDao.findByTemplateId(rftFbTpt.getId());
		resultMap.put("rftFbtemplate",rftFbTpt);//封装模板
		resultMap.put("rftFbTptItems",rftFbItems);//封装条目
		return resultMap;
	}
   
	/*创建或者保存写作提示语模板
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#saveOrUpdaterftRftDimTipTemplate(com.swu.pad.reflection.entity.RftDimTipTemplate)
	 */
	@Override
	public void saveOrUpdaterftRftDimTipTemplate(RftDimTipTemplate rftDimTipTemplate) {
		rftDTTDao.saveAndFlush(rftDimTipTemplate);
	}
    
	/*获取所有  写作提示语模板
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#getRftDimTipTemplates()
	 */
	@Override
	public List<RftDimTipTemplate> getRftDimTipTemplates() {
		return rftDTTDao.findAll();
	}
    
	/*删除一个写作提示语模板
	 * (non-Javadoc)
	 * @see com.swu.pad.reflection.service.ReflectionService#deleteRftDimTipTemplate(java.lang.String)
	 */
	@Override
	public void deleteRftDimTipTemplate(String templateId) {
		 rftDTTDao.delete(templateId); 
		 List<RftDimTips> rftDimTips=rftDimTipsDao.findByTemplateId(templateId);
		 for (int i = 0; i < rftDimTips.size(); i++) {
			 rftDimTipsDao.delete(rftDimTips.get(i));//删除模板关联  条目
		}
	}

	@Override
	public List<RftDimTips> getRftDimTips(String templateId) {
		return rftDimTipsDao.findByTemplateId(templateId);
	}
    
	//保存一个反馈打分
	@Override
	public void saveRftFbItemScore(RftFbItemScore rftFbItemScore) {
		  rftFbItemScore.setTimeStamp(TimeUtil.getStringDate());//设置 时间
		  rftFbItemScore.setFeeling("0");//不是感受  类别的 那么 感受  就赋值 为 "0"
		  rftFbItemScoreDao.saveAndFlush(rftFbItemScore);
	}
    //保存反馈感受
	@Override
	public void saveRftFbFeeling(RftFbItemScore rftFbItemScore) {
		  rftFbItemScore.setTimeStamp(TimeUtil.getStringDate());//设置 时间
		  rftFbItemScoreDao.saveAndFlush(rftFbItemScore);
	}
   
	//删除一个 反思写作提示语 条目 
	@Override
	public void deleteRftTipsItem(String itemId) {
		  rftDimTipsDao.delete(itemId);
	}
    
	
}
